#![cfg(test)]
#![allow(dead_code)]

use std::{
    fs::File,
    io::{self, Read},
    path::{Path, PathBuf},
};

use crate::Expr;

use super::parse;

#[test]
fn parse_proto() {
    let expr = Expr::try_from("(loop 0 10 |x| (println (fib x)))").unwrap();
    println!("{expr:?}")
}

#[test]
fn parse_nested_lambda() {
    let expr = Expr::try_from(
        "(def loop |f t body|
        (begin
            (def inn |n|
                (if (= n t) 
                    (body n) 
                    (begin 
                        (body n)
                        (inn (+ n 1)))))
            (inn f)))",
    )
    .unwrap();

    println!("{expr}")
}

#[test]
fn parse_examples() -> io::Result<()> {
    for file in enumerate_files()? {
        let _ = parse(read_file(file)?).unwrap();
    }
    Ok(())
}

fn enumerate_files() -> std::io::Result<impl Iterator<Item = PathBuf>> {
    let cur = std::env::current_dir()?.join("examples");

    Ok(std::fs::read_dir(cur)?
        .filter(|entry| {
            if let Ok(entry) = entry {
                return entry.path().extension().unwrap() == "dj";
            }
            false
        })
        .map(|entry| entry.unwrap().path()))
}

fn read_file<P: AsRef<Path>>(path: P) -> std::io::Result<String> {
    let mut src_file = File::open(path)?;
    let mut src = String::new();
    src_file.read_to_string(&mut src)?;
    Ok(src)
}
